package com.JingYan.Thread;

import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 线程同步所使用的公用类
 *
 * @author Dong_Jia_Qi on 2022/6/4
 */
@Slf4j
public class Counter {
    public static final Object lock = new Object();
    public static int count = 0;
    private int count1 = 0;
    /**
     * 可重入锁
     */
    public static final Lock reentrantLock =new ReentrantLock();
    private int count2 = 0;
    /**
     * 读写分离锁
     */
    private final ReadWriteLock rwlock = new ReentrantReadWriteLock();
    /**
     * 读锁
     */
    private final Lock rlock = rwlock.readLock();
    /**
     * 写锁
     */
    private final Lock wlock = rwlock.writeLock();
    /**
     * 读写说写入参数
     */
    private int[] counts = new int[10];
    public void add(int n) {
        synchronized(this) {
            count1 += n;
        }
    }

    public synchronized void dec(int n) {
            count1 -= n;
    }

    public int get() {
        return count1;
    }

    /**
     * 可重入锁 加参数
     * @param n
     * @param name
     */
    public void reenAdd(int n, String name){
        // reentrantLock.lock();
        try {
            if (reentrantLock.tryLock(1, TimeUnit.SECONDS)) {
                try {
                    log.info(name+"加操作");
                    count2 += n ;
                } finally {
                    //解锁
                    reentrantLock.unlock();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
    public int reenget() {
        try {
            if (reentrantLock.tryLock(1, TimeUnit.SECONDS)) {
                try {
                    return count2;
                } finally {
                    //解锁
                    reentrantLock.unlock();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();

        }
        return 0;
    }

    /**
     * 读写锁 写操作
     * @param index
     */
    public void rwInc(int index) {
        wlock.lock(); // 加写锁
        try {
            counts[index] += 1;
        } finally {
            wlock.unlock(); // 释放写锁
        }
    }

    /**
     * 读写锁 读操作
     * @return
     */
    public int[] rwGet() {
        rlock.lock(); // 加读锁
        try {
            return Arrays.copyOf(counts, counts.length);
        } finally {
            rlock.unlock(); // 释放读锁
        }
    }
}
